﻿using System;
using System.Reflection;
using System.Collections;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections.Generic;
using System.Diagnostics;
using System.Data;

using FCNS.KeepMoney.Util;
using FCNS.KeepMoney.Configuration;
using FCNS.KeepMoney.Data;

using FCNS;
using FCNS.Controls.Calendars;

namespace FCNS.KeepMoney.UI
{
    public partial class GtdViewMac : Control,IGtdView
    {
        #region 变量
        AceGtd configGtd = Program.AppConfig.Gtd;
        int titleHeight =20;//标题高度
        int tasksHeight = 100;//任务内容的高度
        Bitmap offBmp = null;//用于绘制背景
        System.DateTime firstDate, lastDate;//上个星期,下个星期
        ToolTip tip = new ToolTip();
        int[] columnWidthPlusX = new int[8];//存储日期列的宽度
        Pen penTitle = new Pen(Color.Empty);
        Pen penTask = new Pen(Color.Empty);
        SolidBrush sbTitle = new SolidBrush(Color.Empty);
        SolidBrush sbTask = new SolidBrush(Color.Empty);
        Bitmap offBmpBuffer = null;
        int[] limitsV = new int[7];
        bool movingTask = false;
        string timeFormatText = "H:mm";
        string timeFormatTextLeft = "H:mm";
        Image shadow00, shadow02, shadow10, shadow12, shadow20, shadow21, shadow22;
        List<GtdTask> tasks = new List<GtdTask>();

        /// <summary>
        ///已选择的任务编辑框实例 
        /// </summary>
        OperationMouseStatus lastestMouse;
        #endregion

        Hashtable gtdGroups = new Hashtable();

        GtdTask selectedTask = null;
        public GtdTask SelectedTask
        {
            get { return selectedTask; }
            set { selectedTask = value; }
        }

         GtdData selectedData = null;
         public GtdData SelectedGtdData
         {
             get { return selectedData; }
             set { selectedData = value; }
         }

        System.DateTime date = DateTime.Now;
        /// <summary>
        /// 获取或设置要显示的日期
        /// </summary>
        [Category("FCNS"), Description("当前显示的日期")]
        public System.DateTime Date
        {
            get
            {
                return date;
            }
            set
            {
                date = value;
                UpdateGtdView(true);
            }
        }

        #region 类

        enum OperationMouse
        {
            Resize,
            Move,
            Add,
            None
        }
        /// <summary>
        /// 鼠标移动的操作类
        /// </summary>
        class OperationMouseStatus
        {
            //public System.DateTime start, end;
            public System.TimeSpan duration;
            public System.DateTime mouseDown, mouseUp;
            /// <summary>
            /// 任务类型 0 没有;1 调整大小;2 移动;3 拖动
            /// </summary>
            public OperationMouse operationMouse;
        }

        //struct RectangleViewed
        //{
        //    public int y, y2, day;
        //    public EventTask et;
        //}
        /// <summary>
        /// 任务编辑框类
        /// </summary>
        //public class EventTask
        //{
        //    public System.DateTime Start;
        //    public System.DateTime End;
        //    public GtdData calTask;
        //    public GtdData calData;

        //}
        #endregion


        #region 鼠标操作
        //无代码
        private void MouseDownMonth(System.Windows.Forms.MouseEventArgs e)
        {
            // TODO: MouseDownMonth
        }
        //无代码
        private void DoubleClickMonth(System.Windows.Forms.MouseEventArgs e)
        {
            // TODO: DoubleClickMonth
        }
        //无代码
        private void MouseUpMonth(System.Windows.Forms.MouseEventArgs e)
        {
            // TODO: MouseUpMonth
        }


        private void MouseDownWeekAndDay(System.Windows.Forms.MouseEventArgs e)
        {
            int Y = e.Y;
            selectedTask = null;
            lastestMouse = new OperationMouseStatus();
            lastestMouse.operationMouse = OperationMouse.Add;
            lastestMouse.mouseDown = getPosDateTime(e.X, Y);
            lastestMouse.mouseUp = lastestMouse.mouseDown;

            if (lastestMouse.mouseDown == System.DateTime.MinValue||this.Cursor==Cursors.No)
            {
                lastestMouse = null;
                return;
            }
         
            for (int i = 0; i < tasks.Count; i++)
            {
                if ((Y >= tasks[i].StartY) && (Y <= tasks[i].EndY) &&
                    (e.X >= columnWidthPlusX[tasks[i].Day]) && (e.X <= columnWidthPlusX[tasks[i].Day + 1]))
                {
                    selectedTask = tasks[i];
                    lastestMouse.operationMouse = OperationMouse.Move;

                    if (Y <= (tasks[i].StartY + 5))
                    {
                        lastestMouse.mouseDown = selectedTask.StartTime;
                        lastestMouse.operationMouse = OperationMouse.Resize;

                    }
                    if (Y >= (tasks[i].EndY - 5))
                    {
                        lastestMouse.operationMouse = OperationMouse.Resize;
                        lastestMouse.duration = selectedTask.EndTime - selectedTask.StartTime;
                    }
                    if (lastestMouse.operationMouse == OperationMouse.Resize)
                        lastestMouse.mouseUp = selectedTask.EndTime;
                    break;
                }
            }
        }

        private void MouseMoveWeekAndDay(System.Windows.Forms.MouseEventArgs e)
        {
            if (lastestMouse != null)
            {
                if (e.Button != MouseButtons.Left)
                    return;

                if ((selectedTask == null) && (getPosDateTime(e.X, e.Y) != lastestMouse.mouseDown))
                    lastestMouse.operationMouse = OperationMouse.Add;

                System.DateTime dt = getPosDateTime(e.X, e.Y);

                if (dt != System.DateTime.MinValue)
                {
                    if (lastestMouse.mouseUp == dt)
                        return;

                    lastestMouse.mouseUp = dt;
                    if (lastestMouse.operationMouse == OperationMouse.Move)
                        MoveTask();
                    else if (lastestMouse.operationMouse == OperationMouse.Resize)
                        ReSizeTask(dt);
                    else if (lastestMouse.operationMouse == OperationMouse.Add)
                        NewTask();
                    else
                        return;

                    Repaint2();
                }
            }
            else
            {
                //非时间段内的不能操作鼠标
                if (e.Y < getPosHours(configGtd.StartHour, 0) || e.Y > getPosHours(configGtd.EndHour, 0))
                {
                    this.Cursor = Cursors.No;
                    return;
                }

                Cursor cursor = Cursors.Default;
                for (int i = 0; i < tasks.Count; i++)
                {
                    GtdTask task = tasks[i];
                    if ((e.Y >= task.StartY) && (e.Y <= task.EndY) && (e.X >= columnWidthPlusX[task.Day])
                        && (e.X <= columnWidthPlusX[task.Day + 1]))
                    {
                        cursor = Cursors.SizeAll;

                        if (e.Y <= (task.StartY + 5) || e.Y >= (task.EndY - 5))
                            cursor = Cursors.HSplit;

                        break;
                    }
                }
                this.Cursor = cursor;
            }
        }

        private void MouseUpWeekAndDay(System.Windows.Forms.MouseEventArgs e)
        {
            if (lastestMouse != null)
            {
                if (selectedTask != null)
                {
                    selectedTask.StartY = getPosHours(selectedTask.StartTime.Hour, selectedTask.StartTime.Minute);
                    selectedTask.EndY = getPosHours(selectedTask.EndTime.Hour, selectedTask.EndTime.Minute);

                    if (lastestMouse.operationMouse == OperationMouse.Add)
                    {
                        ChangeTask();
                    }
                    else
                    {
                        //KMData.EditGtdEntry(selectedTask);
                        Program.SaveKMD = true;
                    }
                }
                lastestMouse = null;
                UpdateGtdView(false);
            }
        }

        private void DoubleClickWeekAndDay(System.Windows.Forms.MouseEventArgs e)
        {
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                if (selectedTask== null)
                {
                    //lastestMouse.operationMouse = OperationMouse.Resize;
                    //if (lastestMouse.mouseDown.AddMinutes(-15).Day == lastestMouse.mouseDown.Day)
                    //    lastestMouse.mouseDown = lastestMouse.mouseDown.AddMinutes(-15);

                    //InsertNewGtd();
                    //ChangeGtd();
                    //UpdateGtdView(true);
                    //GtdDataChanged(selected.calTask, 1);
                }
                else
                    ChangeTask();
            }
        }



        /// <summary>
        /// 计算时间所在Y坐标,已包含标题的高度
        /// </summary>
        /// <param name="hour"></param>
        /// <param name="minute"></param>
        /// <returns></returns>
        int getPosHours(double hour, double minute)
        {
            double pos = hour + (minute / 60);
            return (int)((tasksHeight * pos) / 24) + titleHeight;
        }
        /// <summary>
        /// 转换颜色
        /// </summary>
        /// <param name="color"></param>
        /// <returns></returns>
        Color Color2Alpha(Color color)
        {
            return Color.FromArgb(configGtd.Alpha, color.R, color.G, color.B);
        }
        void DrawFillVGradient(Graphics g_, Rectangle rect1, Color color1, Color color2)
        {
            System.Int32 r, g, b;
            for (int i = 0; i < rect1.Height; i++)
            {
                r = color2.R + ((((rect1.Height - 1) - i) * (color1.R - color2.R)) / (rect1.Height - 1));
                g = color2.G + ((((rect1.Height - 1) - i) * (color1.G - color2.G)) / (rect1.Height - 1));
                b = color2.B + ((((rect1.Height - 1) - i) * (color1.B - color2.B)) / (rect1.Height - 1));
                penTitle.Color = Color.FromArgb(255, r, g, b);
                g_.DrawLine(penTitle, rect1.Left, rect1.Top + i, rect1.Right - 1, rect1.Top + i);
            }
        }
        /// <summary>
        /// 计算字符的长度
        /// </summary>
        /// <param name="font1">字符使用的字体</param>
        /// <param name="text">字符内容</param>
        /// <param name="width">绘制字符的方框的宽度</param>
        /// <returns></returns>
        int FontWidth(Font font1, string text, int width)
        {
            int width2 = width + (font1.Height * 2);
            Bitmap auxBmp = new Bitmap(width2, font1.Height);
            Graphics g = Graphics.FromImage(auxBmp);
            g.Clear(Color.White);
            g.DrawString(text, font1, sbTitle, 0, 0);

            int pos = (width2) - 1;
            bool find = false;
            while ((pos > 0) && (!find))
            {
                for (int y = 1; y < font1.Height; y += 3)
                {
                    if (auxBmp.GetPixel(pos, y).R != 255)
                    {
                        find = true;
                        break;
                    }
                }
                pos -= 2;
            }

            g.Dispose();
            auxBmp.Dispose();
            return pos;
        }
        /// <summary>
        /// 获取DateTime.ToString()后的字符
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="type">0 为%d,其它默认</param>
        /// <returns></returns>
        string NameDayType(System.DateTime dt, int type)
        {
            switch (type)
            {
                default:
                    return dt.ToString("yyyy-MM-dd");
            }
        }
        /// <summary>
        /// 获取日期控件宽度
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="width"></param>
        /// <param name="font1"></param>
        /// <param name="max"></param>
        /// <returns></returns>
        int NameDayWidth(System.DateTime dt, int width, Font font1, int max)
        {
            if (max <= 0)
            {
                return 0;
            }
            int op = max;
            string text = NameDayType(dt, max);
            while (FontWidth(font1, text, width) > width)
            {
                op--;
                text = NameDayType(dt, op);
                if (op <= 0) return 0;
            }

            return op;
        }
        #endregion


        public GtdViewMac()
        {
            InitializeComponent();

            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.UserMouse, true);
            this.SetStyle(ControlStyles.ResizeRedraw, false);
            this.SetStyle(ControlStyles.Opaque, true);

            shadow00 = Properties.Resources.shadow_0_0;
            shadow02 = Properties.Resources.shadow_0_2;
            shadow10 = Properties.Resources.shadow_1_0;
            shadow12 = Properties.Resources.shadow_1_2;
            shadow20 = Properties.Resources.shadow_2_0;
            shadow21 = Properties.Resources.shadow_2_1;
            shadow22 = Properties.Resources.shadow_2_2;
        }

        #region 控件刷新
        /// <summary>
        /// 更新控件
        /// </summary>
        /// <param name="forceUpdate">true 重新加载任务</param>
        public void UpdateGtdView(bool refreshData)
        {
            /*先统计要显示的日期数量
           * 绘制任务显示控件的背景和内容(按月和按周两种)
           * 绘制已选择的任务编辑框的阴影效果
           * 刷新控件确认绘制成功,否则再次调用绘制任务*/

            RecalculateDateLimits();
            if (refreshData)
                InitTasks();

            Repaint2();
        }

        private void RecalculateDateLimits()
        {
            System.DateTime first, last;
            switch (configGtd.CalendarStyle)
            {
                case MonthCalendarStyle.Week:
                    for (int i = 0; i < 7; i++)
                    {
                        first = date.AddDays(-i);
                        if (configGtd.DayByWeek == 5)
                        {
                            if (first.DayOfWeek == DayOfWeek.Monday)
                                break;
                        }
                        else
                        {
                            if ((int)first.DayOfWeek == configGtd.FirstDayOfWeek)
                                break;
                        }
                    }
                    first = DateTime.ParseExact(date.ToString("yyyyMMdd"), "yyyyMMdd", null);
                    last = first.AddDays(configGtd.DayByWeek - 1);
                    break;

                case MonthCalendarStyle.Month:
                    first = date;
                    first = first.AddDays(-(date.Day - 1));
                    last = first;
                    last = last.AddDays(System.DateTime.DaysInMonth(last.Year, last.Month) - 1);
                    while ((int)first.DayOfWeek != configGtd.FirstDayOfWeek)
                        first = first.AddDays(-1);

                    while ((int)last.AddDays(1).DayOfWeek != configGtd.FirstDayOfWeek)
                        last = last.AddDays(1);

                    break;

                default:
                    first = last = date;
                    break;
            }
            last = last.AddDays(1).AddSeconds(-1);

            if (((last != lastDate) || (first != firstDate)))
            {
                firstDate = first;
                lastDate = last;
            }
        }

        private void Repaint2()
        {
            if ((this.ClientRectangle.Width < 1) || (this.ClientRectangle.Height < 1))
                return;

            if ((offBmp == null) || (offBmp.Height != this.ClientRectangle.Height) || (offBmp.Width != this.ClientRectangle.Width))
            {
                if (offBmp != null)
                    offBmp.Dispose();

                offBmp = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);
            }
            Graphics g = GenerateBackground();

            if (configGtd.CalendarStyle == MonthCalendarStyle.Month)
            {
                PaintStyleMonth(g);
                PaintTasksMonth(g);
            }
            else
            {
                PaintStyleWeekAndDay(g);
                DrawTasks(g);
            }

            if (configGtd.CalendarStyle != MonthCalendarStyle.Month && selectedTask != null)
                DrawTask(g, selectedTask);

            g.Dispose();
            Paint2();
        }

        private void Paint2()
        {
            if ((offBmp == null) || (offBmp.Height != this.ClientRectangle.Height) || (offBmp.Width != this.ClientRectangle.Width))
            {
                Repaint2();
                return;
            }
            if ((this.ClientRectangle.Width < 1) || (this.ClientRectangle.Height < 1))
                return;

            if (!this.IsDisposed)//取消这里会导致控件无法刷新,不加验证在切换模式的时候会报错
            {
                Graphics drawingSurface = Graphics.FromHwnd(this.Handle);
                drawingSurface.DrawImage(offBmp, 0, 0);
                drawingSurface.Dispose();
            }
        }
       
        private Graphics GenerateBackground()
        {
            if ((movingTask) && (offBmpBuffer != null))
            {
                if (offBmp != null)
                    offBmp.Dispose();

                offBmp = (Bitmap)offBmpBuffer.Clone(new Rectangle(0, 0, offBmpBuffer.Width, offBmpBuffer.Height), offBmpBuffer.PixelFormat);
                return Graphics.FromImage(offBmp);
            }
            if ((offBmp == null) || (offBmp.Height != this.ClientRectangle.Height) || (offBmp.Width != this.ClientRectangle.Width))
            {
                if (offBmp != null)
                    offBmp.Dispose();

                offBmp = new Bitmap(this.ClientRectangle.Width, tasksHeight);
            }

            Graphics g = Graphics.FromImage(offBmp);
            g.Clear(Color.White);
          
            if (movingTask)
                offBmpBuffer = (Bitmap)offBmp.Clone(new Rectangle(0, 0, offBmp.Width, offBmp.Height), offBmp.PixelFormat);

            return g;
        }
        #endregion


        #region 绘制函数
        /// <summary>
        /// 获取鼠标点击处的日期时间段
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        System.DateTime getPosDateTime(double x, double y)
        {
            System.DateTime aux = System.DateTime.MinValue;
            if (x < columnWidthPlusX[0] || x >= this.ClientRectangle.Width || y < 0 || y >= this.Height)
                return aux;

            int minutes = (15 * (int)System.Math.Round(((((y - titleHeight) * (24 * 60)) / tasksHeight)) / 15));
            aux = new System.DateTime(firstDate.Year, firstDate.Month, firstDate.Day);
            aux = aux.AddMinutes(minutes);
            int i = 0;
            while (aux <= lastDate)
            {
                if ((x >= columnWidthPlusX[i]) && (x <= columnWidthPlusX[i + 1]))
                    break;

                i++;
                aux = aux.AddDays(1);
            }
            return aux;
        }



        /// <summary>
        /// 保存当前编辑框内容
        /// </summary>
        private void SaveText()
        {
            if (textBox1.Visible)
            {
                Debug.Assert(selectedTask != null);

                selectedTask.Title = textBox1.Text;
                //KMData.EditGtdEntry(selectedTask);
                Program.SaveKMD = true;
                textBox1.Visible = false;
                Repaint2();
            }
        }

      
        private void PaintText(Graphics g, Font font1, SolidBrush brush, string text, int x, int y, int width, int height)
        {
            int height2 = font1.Height;
            while ((height2 + font1.Height) < height) height2 += font1.Height;
            RectangleF drawRect = new RectangleF(x, y, width, height2);
            g.DrawString(text, font1, brush, drawRect);
        }
       
        private void PaintStyleWeekAndDay(Graphics g)
        {
            //计算列宽
            titleHeight = 20;
            int x;
            int maxDay = (configGtd.CalendarStyle == MonthCalendarStyle.Day) ? 1 : configGtd.DayByWeek;

            columnWidthPlusX[0] = 40;
            columnWidthPlusX[maxDay] = this.ClientRectangle.Width - 1;
            for (int i = 1; i < maxDay; i++)
                columnWidthPlusX[i] = (((columnWidthPlusX[configGtd.DayByWeek] - 40) * i) / configGtd.DayByWeek) + 40;
            
            //标题日期背景占15px
            for (int i = 1; i <= 6; i++)
            {
                x = 255 - (i * 3);
                penTitle.Color = Color.FromArgb(255, x, x, x);
                g.DrawLine(penTitle, 0, i, this.ClientRectangle.Width, i);
                g.DrawLine(penTitle, 0, 14 - i, this.ClientRectangle.Width, 14 - i);
            }
            penTitle.Color = Color.FromArgb(255, 234, 234, 234);
            g.DrawLine(penTitle, 0, 7, this.ClientRectangle.Width, 7);

            penTitle.Color = Color.FromArgb(255, 203, 203, 203);
            for (int i = 0; i <= maxDay; i++)
                g.DrawLine(penTitle, columnWidthPlusX[i], 0, columnWidthPlusX[i], this.ClientRectangle.Height);

            penTitle.Color = Color.FromArgb(255, 203, 203, 203);
            g.DrawLine(penTitle, 0, 15, this.ClientRectangle.Width, 15);

            penTitle.Color = Color.FromArgb(255, 110, 110, 110);
            g.DrawLine(penTitle, 0, titleHeight - 1, this.ClientRectangle.Width, titleHeight - 1);
            g.DrawLine(penTitle, 0, titleHeight - 5, this.ClientRectangle.Width, titleHeight - 5);
            penTitle.Color = Color.FromArgb(255, 206, 206, 206);
            for (int i = 2; i <= 4; i++)
                g.DrawLine(penTitle, 0, titleHeight - i, this.ClientRectangle.Width, titleHeight - i);
            
            PaintDays(g);
            PaintHours(g);

            sbTask.Color = Color.FromArgb(30, 0, 0, 0);
            g.FillRectangle(sbTask, 0, 0, this.ClientRectangle.Width, getPosHours(configGtd.StartHour, 0));
            g.FillRectangle(sbTask, 0, getPosHours(configGtd.EndHour, 0), this.ClientRectangle.Width, this.ClientRectangle.Height - getPosHours(configGtd.EndHour, 0));
        }
       
        private void PaintDays(Graphics g)
        {
            Font font1 = new Font("宋体", 9, FontStyle.Bold);
            StringFormat align1 = new StringFormat();
            align1.Alignment = StringAlignment.Center;
            sbTitle.Color = Color.FromArgb(255, 0, 0, 0);
            g.DrawString(date.Year.ToString(), font1, sbTitle, columnWidthPlusX[0] / 2, (16 - font1.Height) / 2, align1);

            System.DateTime dt = firstDate;
            int i = 0;

            int max = 4;
            while (dt < lastDate)
            {
                max = NameDayWidth(dt, columnWidthPlusX[i + 1] - (columnWidthPlusX[i] + 10), font1, max);
                i++;
                dt = dt.AddDays(1);
            }

            SolidBrush sb2 = new SolidBrush(Color.Blue);
            dt = firstDate;
            i = 0;
            while (dt < lastDate)
            {
                //填充今日日期区域的颜色
                if (dt.ToString("yyyyMMdd") == System.DateTime.Now.ToString("yyyyMMdd"))
                {
                    Rectangle rect1 = new Rectangle(columnWidthPlusX[i] + 1, 0, columnWidthPlusX[i + 1] - columnWidthPlusX[i] - 1, 8);
                    DrawFillVGradient(g, rect1, Color.FromArgb(255, 208, 226, 245), Color.FromArgb(255, 104, 169, 234));
                    rect1 = new Rectangle(columnWidthPlusX[i] + 1, 7, columnWidthPlusX[i + 1] - columnWidthPlusX[i] - 1, 9);
                    DrawFillVGradient(g, rect1, Color.FromArgb(255, 104, 169, 234), Color.FromArgb(255, 187, 252, 255));
                    penTitle.Color = Color.FromArgb(255, 102, 147, 192);
                    g.DrawLine(penTitle, columnWidthPlusX[i] + 1, 15, columnWidthPlusX[i + 1], 15);
                    g.DrawLine(penTitle, columnWidthPlusX[i + 1], 0, columnWidthPlusX[i + 1], 15);

                    sbTitle.Color = Color.FromArgb(255, 236, 243, 252);
                    g.FillRectangle(sbTitle, columnWidthPlusX[i] + 1, 16, columnWidthPlusX[i + 1] - columnWidthPlusX[i] - 1, titleHeight - 21);
                    sbTitle.Color = Color.FromArgb(255, 0, 0, 0);
                }
                g.DrawString(NameDayType(dt, max), font1, sbTitle, (columnWidthPlusX[i] + columnWidthPlusX[i + 1]) / 2, (16 - font1.Height) / 2, align1);

                i++;
                dt = dt.AddDays(1);
            }
            sb2.Dispose();
            align1.Dispose();
            font1.Dispose();
        }
      
        private void PaintHours(Graphics g)
        {
            int x;
            Color colorLight = Color.FromArgb(255, 229, 229, 229);
            Color colorDark = Color.FromArgb(255, 204, 204, 204);

            //int totalMediumHours = (configGtd.EndHour-configGtd.StartHour) * 2;
            //for (int i = configGtd.StartHour; i < totalMediumHours; i++)
            //{
            //    if ((i % 2) == 0)
            //        penTask.Color = colorDark;
            //    else
            //        penTask.Color = colorLight;

            //    x = (tasksHeight * i) / totalMediumHours + titleHeight;
            //    //MessageBox.Show(tasksHeight.ToString()+" "+i.ToString()+"  "+((tasksHeight * i) / totalMediumHours ).ToString()+" "+ x.ToString());
            //    g.DrawLine(penTask, 40, x, this.ClientRectangle.Width, x);
            //}
            int totalMediumHours = 24 * 2;
            for (int i = 1; i < totalMediumHours; i++)
            {
                if ((i % 2) == 0)
                    penTask.Color = colorDark;
                else
                    penTask.Color = colorLight;

                x = (tasksHeight * i) / totalMediumHours + titleHeight;
                g.DrawLine(penTask, 40, x, this.ClientRectangle.Width, x);
            }
            StringFormat align1 = new StringFormat();
            align1.Alignment = StringAlignment.Far;
            sbTask.Color = Color.FromArgb(255, 0, 0, 0);

            //for (int i =configGtd.StartHour+1; i < configGtd.EndHour; i++)
            //{
            //    System.DateTime a = new System.DateTime(1, 1, 1, i, 0, 0);
            //    g.DrawString(a.ToString(timeFormatTextLeft), this.Font, sbTask, 38, ((tasksHeight * i) / 24) - this.Font.Height / 2 + titleHeight, align1);
            //}
            for (int i = 1; i <= 23; i++)
            {
                System.DateTime a = new System.DateTime(1, 1, 1, i, 0, 0);
                g.DrawString(a.ToString(timeFormatTextLeft), this.Font, sbTask, 38, ((tasksHeight * i) / 24) - this.Font.Height / 2 + titleHeight, align1);
            }
            align1.Dispose();
        }


        private void DrawTasks(Graphics g)
        {
            foreach (GtdTask task in tasks )
                  DrawTask(g, task);
        }

        private void DrawTask(Graphics g, GtdTask task)
        {
            System.DateTime end = task.EndTime;
            if ((end.Hour == 0) && (end.Minute == 0))
            {
                if (task.StartTime != end)
                    end = end.AddSeconds(-1);
                else
                    end = end.AddMinutes(30);
            }

            if (task.StartTime.Day != end.Day)
            {
                int i = -1;
                System.DateTime aux;
                System.DateTime start;
                System.DateTime aux2;
                aux = new System.DateTime(end.Year, end.Month, end.Day, 0, 0, 0);
                drawPartTask(g, task, aux, end, false, true);
                start = end.AddDays(i);
                while (start.Day != task.StartTime.Day)
                {
                    aux = new System.DateTime(start.Year, start.Month, start.Day, 0, 0, 0);
                    aux2 = new System.DateTime(start.Year, start.Month, start.Day, 23, 59, 59);
                    drawPartTask(g, task, aux, aux2, false, false);
                    i--;
                    start = end.AddDays(i);
                }
                aux = new System.DateTime(task.StartTime.Year, task.StartTime.Month, task.StartTime.Day, 23, 59, 59);
                drawPartTask(g, task, task.StartTime, aux, true, false);
            }
            else
            {
                drawPartTask(g, task, task.StartTime, end, true, true);
            }
        }
    
        private void drawPartTask(Graphics g, GtdTask task, System.DateTime start, System.DateTime end, bool drawBegin, bool drawEnd)
        {
            if ((end > lastDate) || (start < firstDate))
            {
                return;
            }

            int x = getPosHours(start.Hour, start.Minute);
            int x2 = getPosHours(end.Hour, end.Minute);
            if ((x == 0) && (x2 == 0))
                return;

            if ((x2 - x) < getPosHours(0, 30))
                x2 = getPosHours(start.Hour, start.Minute + 30);

            if (x2 < x)
                x2 = x + getPosHours(0, 30) + 1;

            if (!drawBegin)
                x -= 15;

            if (!drawEnd)
                x2 += 7;

            int day = 0;
            while (firstDate.AddDays(day).DayOfWeek != start.DayOfWeek)
                day++;

            task.Day = day;

            // 当任务编辑框移动的时候绘制背景阴影
            if (offBmpBuffer == null)
            {
                // 如果只是选中控件,就只绘制背景阴影
                if (task == selectedTask)
                {
                    Rectangle destRect1;
                    System.Drawing.Imaging.ImageAttributes ia = new System.Drawing.Imaging.ImageAttributes();
                    ia.SetWrapMode(WrapMode.Tile);
                    destRect1 = new Rectangle(columnWidthPlusX[day] - 5, x + 5, shadow00.Width, shadow00.Height);
                    g.DrawImage(shadow00, destRect1, 0, 0, shadow00.Width, shadow00.Height, GraphicsUnit.Pixel, ia);
                    destRect1 = new Rectangle(columnWidthPlusX[day + 1] + 1, x + 5, shadow02.Width, shadow02.Height);
                    g.DrawImage(shadow02, destRect1, 0, 0, shadow02.Width, shadow02.Height, GraphicsUnit.Pixel, ia);
                    destRect1 = new Rectangle(columnWidthPlusX[day] - 5, x2 - 6, shadow20.Width, shadow20.Height);
                    g.DrawImage(shadow20, destRect1, 0, 0, shadow20.Width, shadow20.Height, GraphicsUnit.Pixel, ia);
                    destRect1 = new Rectangle(columnWidthPlusX[day + 1] - 9, x2 - 6, shadow22.Width, shadow22.Height);
                    g.DrawImage(shadow22, destRect1, 0, 0, shadow22.Width, shadow22.Height, GraphicsUnit.Pixel, ia);
                    destRect1 = new Rectangle(columnWidthPlusX[day] - 5, x + 5 + shadow00.Height, shadow10.Width, x2 - 6 - (x + 5 + shadow00.Height));
                    g.DrawImage(shadow10, destRect1, 0, 0, shadow10.Width, shadow10.Height, GraphicsUnit.Pixel, ia);
                    destRect1 = new Rectangle(columnWidthPlusX[day + 1] + 1, x + 5 + shadow00.Height, shadow12.Width, x2 - 6 - (x + 5 + shadow00.Height));
                    g.DrawImage(shadow12, destRect1, 0, 0, shadow12.Width, shadow12.Height, GraphicsUnit.Pixel, ia);
                    destRect1 = new Rectangle(columnWidthPlusX[day] - 5 + shadow20.Width, x2, columnWidthPlusX[day + 1] - 9 - (columnWidthPlusX[day] - 5 + shadow20.Width), shadow21.Height);
                    g.DrawImage(shadow21, destRect1, 0, 0, shadow21.Width, shadow21.Height, GraphicsUnit.Pixel, ia);
                    ia.Dispose();
                }
            }
            PaintTasksPref(g, task, columnWidthPlusX[day] + 1, x + 1, columnWidthPlusX[day + 1] - columnWidthPlusX[day] - 1, x2 - 1);

            int alpha2 = 255;
            if (offBmpBuffer != null)
            {
                alpha2 = configGtd.Alpha;
            }
            else
            {
                alpha2 = 255;
            }

            // 相同颜色的选择与不选择部分
            Color color = task.GtdGroup.ColorBorder;
            color = Color.FromArgb(alpha2, color.R, color.G, color.B);
            penTask.Color = color;

            //边框
            g.DrawLine(penTask, columnWidthPlusX[day], x + 6, columnWidthPlusX[day], x2 - 7);
            g.DrawLine(penTask, columnWidthPlusX[day + 1], x + 6, columnWidthPlusX[day + 1], x2 - 7);
            g.DrawLine(penTask, columnWidthPlusX[day] + 6, x, columnWidthPlusX[day + 1] - 6, x);
            g.DrawLine(penTask, columnWidthPlusX[day] + 6, x2 - 1, columnWidthPlusX[day + 1] - 6, x2 - 1);
            //右下部分
            g.DrawLine(penTask, columnWidthPlusX[day + 1] - 5, x2 - 2, columnWidthPlusX[day + 1] - 4, x2 - 2);
            g.DrawLine(penTask, columnWidthPlusX[day + 1] - 2, x2 - 4, columnWidthPlusX[day + 1] - 3, x2 - 3);
            g.DrawLine(penTask, columnWidthPlusX[day + 1] - 1, x2 - 6, columnWidthPlusX[day + 1] - 1, x2 - 5);
            //左下部分
            g.DrawLine(penTask, columnWidthPlusX[day] + 4, x2 - 2, columnWidthPlusX[day] + 5, x2 - 2);
            g.DrawLine(penTask, columnWidthPlusX[day] + 3, x2 - 3, columnWidthPlusX[day] + 2, x2 - 4);
            g.DrawLine(penTask, columnWidthPlusX[day] + 1, x2 - 6, columnWidthPlusX[day] + 1, x2 - 5);
            //左上部分
            g.DrawLine(penTask, columnWidthPlusX[day] + 4, x + 1, columnWidthPlusX[day] + 5, x + 1);
            g.DrawLine(penTask, columnWidthPlusX[day] + 3, x + 2, columnWidthPlusX[day] + 2, x + 3);
            g.DrawLine(penTask, columnWidthPlusX[day] + 1, x + 4, columnWidthPlusX[day] + 1, x + 5);
            //Arriba Derecha
            g.DrawLine(penTask, columnWidthPlusX[day + 1] - 5, x + 1, columnWidthPlusX[day + 1] - 4, x + 1);
            g.DrawLine(penTask, columnWidthPlusX[day + 1] - 3, x + 2, columnWidthPlusX[day + 1] - 2, x + 3);
            g.DrawLine(penTask, columnWidthPlusX[day + 1] - 1, x + 4, columnWidthPlusX[day + 1] - 1, x + 5);

            sbTask.Color = color;
            StringFormat align1 = new StringFormat();
            Font font1 = new Font(this.Font.FontFamily, 9, FontStyle.Bold);
            //如果任务编辑框高度足够就绘制上面和下面的时间,否则只绘制下面的时间
            string s = task.Title;
            //if (showTitle)
            //{
            //    if (task.Title == "" && titleLength != 0)
            //    {
            //        if (task.calTask.Summary.Length > titleLength)
            //        {
            //            s = task.calTask.Summary.Substring(0, titleLength);
            //        }
            //    }
            //    else
            //    {
            //        s = task.calTask.Title;
            //    }
            //}

            if ((x2 - x - 1) > 30)
            {
                //if (task.Selected)
                //{
                    g.DrawLine(penTask, columnWidthPlusX[day] + 6, x + 1, columnWidthPlusX[day + 1] - 6, x + 1);
                    g.DrawLine(penTask, columnWidthPlusX[day] + 4, x + 2, columnWidthPlusX[day + 1] - 4, x + 2);
                    g.DrawLine(penTask, columnWidthPlusX[day] + 3, x + 3, columnWidthPlusX[day + 1] - 3, x + 3);
                    g.DrawLine(penTask, columnWidthPlusX[day] + 2, x + 4, columnWidthPlusX[day + 1] - 2, x + 4);
                    g.DrawLine(penTask, columnWidthPlusX[day] + 2, x + 5, columnWidthPlusX[day + 1] - 2, x + 5);
                    color = task.GtdGroup.ColorBorder;
                    color = Color.FromArgb(alpha2, color.R, color.G, color.B);
                    sbTask.Color = color;
                    g.FillRectangle(sbTask, columnWidthPlusX[day] + 1, x + 6, columnWidthPlusX[day + 1] - columnWidthPlusX[day] - 1, 9);
                    sbTask.Color = task.GtdGroup.ColorText;
                //}
                if (task.Finish)
                {
                    g.DrawString("√ " + task.StartTime.ToString(timeFormatText), font1, sbTask, columnWidthPlusX[day] + 5, x, align1);
                }
                else
                {
                    g.DrawString(task.StartTime.ToString(timeFormatText), font1, sbTask, columnWidthPlusX[day] + 5, x, align1);
                }
                if ((selectedTask == task) && (lastestMouse != null) && drawEnd)
                {
                    align1.Alignment = StringAlignment.Far;
                    g.DrawString(task.EndTime.ToString(timeFormatText), font1, sbTask, columnWidthPlusX[day + 1] - 3, x2 - (font1.Height + 3), align1);
                }
                if (configGtd.CalendarStyle == MonthCalendarStyle.Day)
                {
                    PaintText(g, font1, sbTask, task.Title + " => " + task.Note, columnWidthPlusX[day] + 5, x + 17, columnWidthPlusX[day + 1] - columnWidthPlusX[day] - 8, x2 - x - 16);
                }
                else
                {
                    PaintText(g, font1, sbTask, s, columnWidthPlusX[day] + 5, x + 17, columnWidthPlusX[day + 1] - columnWidthPlusX[day] - 8, x2 - x - 16);
                }
            }
            else
            {
                //if (task.Selected)
                //{
                    sbTask.Color = task.GtdGroup.ColorText;
                //}
                if (configGtd.CalendarStyle == MonthCalendarStyle.Day)
                {
                    PaintText(g, font1, sbTask, task.Title + " => " + task.Note, columnWidthPlusX[day] + 5, x + 2, columnWidthPlusX[day + 1] - columnWidthPlusX[day] - 8, x2 - x - 1);
                }
                else
                {
                    PaintText(g, font1, sbTask, s, columnWidthPlusX[day] + 5, x + 2, columnWidthPlusX[day + 1] - columnWidthPlusX[day] - 8, x2 - x - 1);
                }
                if ((selectedTask == task) && (lastestMouse != null) && (lastestMouse.operationMouse== OperationMouse.Resize) && drawEnd)
                {
                    align1.Alignment = StringAlignment.Far;
                    g.DrawString(task.EndTime.ToString(timeFormatText), font1, sbTask, columnWidthPlusX[day + 1] - 3, x2 - (font1.Height + 3), align1);
                }
            }
            align1.Dispose();
            font1.Dispose();
        }
    
        private void PaintTasksPref(Graphics g, GtdTask task, int x1, int y1, int ancho, int alto)
        {
            int red, green, blue, red2, green2, blue2;
            int i;

            red = task.GtdGroup.ColorBgSelectedLeft.R;
            green = task.GtdGroup.ColorBgSelectedLeft.G;
            blue = task.GtdGroup.ColorBgSelectedLeft.B;
            red2 = task.GtdGroup.ColorBgSelectedRight.R - red;
            green2 = task.GtdGroup.ColorBgSelectedRight.G - green;
            blue2 = task.GtdGroup.ColorBgSelectedRight.B - blue;

            int alpha2 = 255;
            if (offBmpBuffer != null)
            {
                alpha2 = configGtd.Alpha;
            }
            else
            {
                alpha2 = 255;
            }

            //if (task.Selected)
            //{
                if ((alto - y1 + 1) > 30)
                {
                    i = 0;
                    y1 = y1 + 14;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1, x1 + i, alto - 6);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1, x1 + i, alto - 4);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1, x1 + i, alto - 3);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1, x1 + i, alto - 2);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1, x1 + i, alto - 2);
                    i = ancho - 5;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1, x1 + i, alto - 2);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1, x1 + i, alto - 2);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1, x1 + i, alto - 3);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1, x1 + i, alto - 4);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1, x1 + i, alto - 6);
                }
                else
                {
                    i = 0;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1 + 5, x1 + i, alto - 6);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1 + 3, x1 + i, alto - 4);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1 + 2, x1 + i, alto - 3);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1 + 1, x1 + i, alto - 2);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1 + 1, x1 + i, alto - 2);
                    i = ancho - 5;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1 + 1, x1 + i, alto - 2);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1 + 1, x1 + i, alto - 2);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1 + 2, x1 + i, alto - 3);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1 + 3, x1 + i, alto - 4);
                    i++;
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1 + 5, x1 + i, alto - 6);
                }
                for (i = 5; i < (ancho - 5); i++)
                {
                    penTask.Color = Color.FromArgb(alpha2, (red + ((i * red2) / ancho)), (green + ((i * green2) / ancho)), (blue + ((i * blue2) / ancho)));
                    g.DrawLine(penTask, x1 + i, y1, x1 + i, alto - 1);
                }
            //}
            //else
            //{
            //    penTask.Color = Color2Alpha(task.GtdGroup.ColorBgUnselected);
            //    sbTask.Color = Color2Alpha(task.GtdGroup.ColorBgUnselected);
            //    i = 0;
            //    g.DrawLine(penTask, x1 + i, y1 + 5, x1 + i, alto - 6);
            //    i++;
            //    g.DrawLine(penTask, x1 + i, y1 + 3, x1 + i, alto - 4);
            //    i++;
            //    g.DrawLine(penTask, x1 + i, y1 + 2, x1 + i, alto - 3);
            //    i++;
            //    g.DrawLine(penTask, x1 + i, y1 + 1, x1 + i, alto - 2);
            //    i++;
            //    g.DrawLine(penTask, x1 + i, y1 + 1, x1 + i, alto - 2);
            //    i = ancho - 5;
            //    g.DrawLine(penTask, x1 + i, y1 + 1, x1 + i, alto - 2);
            //    i++;
            //    g.DrawLine(penTask, x1 + i, y1 + 1, x1 + i, alto - 2);
            //    i++;
            //    g.DrawLine(penTask, x1 + i, y1 + 2, x1 + i, alto - 3);
            //    i++;
            //    g.DrawLine(penTask, x1 + i, y1 + 3, x1 + i, alto - 4);
            //    i++;
            //    g.DrawLine(penTask, x1 + i, y1 + 5, x1 + i, alto - 6);
            //    g.FillRectangle(sbTask, x1 + 5, y1, ancho - 10, alto - y1);
            //}
        }

     
        private void PaintStyleMonth(Graphics g)
        {
            titleHeight = 40;
            Font font1 = new Font("宋体", 9, FontStyle.Bold);
            StringFormat align1 = new StringFormat();
            align1.Alignment = StringAlignment.Center;
            sbTitle.Color = Color.FromArgb(255, 0, 0, 0);
            g.DrawString(date.ToString("MMMM yyyy"), font1, sbTitle, this.ClientRectangle.Width / 2, (16 - font1.Height) / 2, align1);

            //内容
            int rows = ((lastDate - firstDate).Days / 7) + 1;
            penTask.Color = Color.FromArgb(255, 204, 204, 204);
            for (int i = 0; i <= 7; i++)
                columnWidthPlusX[i] = (this.ClientRectangle.Width * i) / 7;
            
            for (int i = 0; i <= rows; i++)
                limitsV[i] = titleHeight + (((tasksHeight - titleHeight) * i) / rows);
            
            for (int i = 1; i <= 6; i++)
                g.DrawLine(penTask, columnWidthPlusX[i], limitsV[0], columnWidthPlusX[i], tasksHeight);
            
            for (int i = 0; i < rows + 1; i++)
                g.DrawLine(penTask, 0, limitsV[i], this.ClientRectangle.Width, limitsV[i]);


            int col, row;
            System.DateTime dt = firstDate;
            col = row = 0;
            int status = 0;
            Color colorLight = Color.FromArgb(255, 198, 198, 198);
            Color colorDark = Color.FromArgb(255, 64, 64, 64);
            Color colorBlack = Color.FromArgb(255, 0, 0, 0);
            Color color = colorLight;
            StringFormat alignRight = new StringFormat();
            alignRight.Alignment = StringAlignment.Far;
            while (dt < lastDate)
            {
                if (dt.ToString("yyyyMMdd") == date.ToString("yyyyMMdd"))
                {
                    sbTask.Color = Color.FromArgb(255, 247, 247, 247);
                    g.FillRectangle(sbTask, columnWidthPlusX[col] + 1, limitsV[row] + 1, columnWidthPlusX[col + 1] - columnWidthPlusX[col] - 1, limitsV[row + 1] - limitsV[row] - 1);
                }
                if (dt.ToString("yyyyMMdd") == System.DateTime.Now.ToString("yyyyMMdd"))
                {
                    sbTask.Color = Color.FromArgb(255, 170, 230, 250);
                    g.FillRectangle(sbTask, columnWidthPlusX[col] + 1, limitsV[row] + 1, columnWidthPlusX[col + 1] - columnWidthPlusX[col] - 1, limitsV[row + 1] - limitsV[row] - 1);
                }

                if (dt.Day == 1)
                {
                    if (status == 1)
                    {
                        color = colorLight;
                        status = 2;
                    }
                    if (status == 0)
                    {
                        color = colorDark;
                        status = 1;
                    }
                }
                sbTask.Color = color;
                g.DrawString(dt.Day.ToString(), this.Font, sbTask, columnWidthPlusX[col + 1] - 4, limitsV[row] + 2, alignRight);

                col++;
                if (col == 7)
                {
                    col = 0;
                    row++;
                }
                dt = dt.AddDays(1);
            }

            sbTask.Color = colorBlack;
            dt = firstDate;
            alignRight.Alignment = StringAlignment.Center;

            for (int i = 0; i <= 6; i++)
            {
                g.DrawString(dt.ToString("dddd"), font1, sbTask, (columnWidthPlusX[i] + columnWidthPlusX[i + 1]) / 2, limitsV[0] - font1.Height, alignRight);
                dt = dt.AddDays(1);
            }

            align1.Dispose();
            alignRight.Dispose();
            font1.Dispose();
        }
        
        private void PaintTasksMonth(Graphics g)
        {
            int col = 0;
            int row = 0;
            int line = 0;
            System.DateTime dt = firstDate;
            while (dt < lastDate)
            {
                line = 0;
                foreach (GtdTask task in tasks)
                {
                    if (dt.ToString("yyyyMMdd") == task.StartTime.ToString("yyyyMMdd"))
                    {
                        drawTaskMonth(g, task, col, row, line);
                        line++;
                    }
                }
                col++;
                if (col == 7)
                {
                    col = 0;
                    row++;
                }
                dt = dt.AddDays(1);
            }
        }
        
        private void drawTaskMonth(Graphics g, GtdTask et, int col, int row, int line)
        {
            Font font1 = new Font(this.Font.FontFamily, 9, FontStyle.Bold);
            sbTask.Color = et.GtdGroup.ColorBorder;
            int y = limitsV[row] + 5 + (line * 13) + 11;
            if (y < limitsV[row + 1] - 11)
            {
                if (et.Title != "")
                {
                    PaintText(g, font1, sbTask, et.StartTime.ToString(timeFormatText) + " " + et.Title, columnWidthPlusX[col] + 5, y, columnWidthPlusX[col + 1] - columnWidthPlusX[col] - 5, 11);
                }
                else
                {
                    string s = et.Note;
                    if (et.Note.Length > titleHeight)
                    {
                        PaintText(g, font1, sbTask, et.StartTime.ToString(timeFormatText) + " " + et.Note.Substring(0, titleHeight), columnWidthPlusX[col] + 5, y, columnWidthPlusX[col + 1] - columnWidthPlusX[col] - 5, 11);
                    }
                    else
                    {
                        PaintText(g, font1, sbTask, et.StartTime.ToString(timeFormatText) + " " + et.Note, columnWidthPlusX[col] + 5, y, columnWidthPlusX[col + 1] - columnWidthPlusX[col] - 5, 11);
                    }
                }
            }
            font1.Dispose();
        }
        #endregion


        #region 事件
        private void CalendarTask_Resize(object sender, EventArgs e)
        {
            tasksHeight = this.ClientRectangle.Height - titleHeight;
            Repaint2();
        }

        private void CalendarTask_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawImage(offBmp, 0, 0);
        }

        private void CalendarTask_MouseMove(object sender, MouseEventArgs e)
        {
            if (configGtd.CalendarStyle != MonthCalendarStyle.Month)
                MouseMoveWeekAndDay(e);
        }

        private void CalendarTask_MouseDown(object sender, MouseEventArgs e)
        {
            SaveText();
            if (configGtd.CalendarStyle == MonthCalendarStyle.Month)
                MouseDownMonth(e);
            else
                MouseDownWeekAndDay(e);

            if (e.Clicks == 2)
            {
                if (configGtd.CalendarStyle == MonthCalendarStyle.Month)
                    DoubleClickMonth(e);
                else
                    DoubleClickWeekAndDay(e);
            }
        }

        private void CalendarTask_MouseUp(object sender, MouseEventArgs e)
        {
            if (configGtd.CalendarStyle == MonthCalendarStyle.Month)
                MouseUpMonth(e);
            else
                MouseUpWeekAndDay(e);
        }

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Escape:
                    textBox1.Text = selectedTask.Title;
                    SaveText();
                    e.Handled = true;
                    break;
                case Keys.Enter:
                    SaveText();
                    e.Handled = true;
                    break;
            }
        }

        private void textBox1_Leave(object sender, EventArgs e)
        {
            SaveText();
        }

        private void OnKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete && selectedTask != null)
            {
                RemoveTask(selectedTask);
            }
        }

        ////自定义事件
        ///// <summary>
        ///// 当月历显示类型改变后引发任务
        ///// </summary>
        ///// 
        //protected virtual void OnStyleChanged()
        //{
        //    if (StyleChanged != null)
        //    {
        //        StyleChanged(this, System.EventArgs.Empty);
        //    }
        //}
        //[Category("FCNS"), Description("显示类型改变时引发")]
        //new public event EventHandler StyleChanged;

        //protected virtual void OnCalendarChanged()
        //{
        //    if (CalendarChanged != null) CalendarChanged(this, System.EventArgs.Empty);
        //}
        //[Category("FCNS"), Description("任务栏目索引改变时引发")]
        //public event EventHandler CalendarChanged;

        //protected virtual void OnDateChanged()
        //{
        //    if (DateChanged != null)
        //        DateChanged(this, System.EventArgs.Empty);
        //}
        ///// <summary>
        ///// 当日期改变时引发
        ///// </summary>
        //[Category("FCNS"), Description("当前日期改变时引发")]
        //public event EventHandler DateChanged;
        ///// <summary>
        ///// 
        ///// </summary>
        ///// <param name="oper">0 时间改变;1 新增;2 删除</param>
        //public delegate void GtdDataHandler(GtdData task, int oper);
        #endregion

    }
}
